<?php

namespace app\controllers;

use app\models\CommonModel;
use Yii;
use yii\base\Exception;
use yii\web\Controller;
use yii\web\Response;

/**
 * Class BaseController
 * @package app\controllers
 */
class BaseController extends Controller
{

    /**
     * 获取[post]参数
     * @param null $param 要获取的参数[key]
     * @param bool $format 是否格式化
     * @param mixed $default 初始值
     * @return array|mixed|string|null
     */
    protected function post($param = null, $format = true, $default = '')
    {

        $request = Yii::$app->request->post();
        $end = [];
        if ($param && isset($request[$param])) {

            // 非数组才进行去两端空格
            $end = $request[$param];
        } elseif (!isset($request[$param])) {

            $end = null;
        } else {

            $end = $request;
        }

        // 非空的格式化一下
        if ($end && !empty($end)) $end = $this->formatParams($end, $format);

        // 默认值
        if (empty($end) && isset($default)) {
            return $default;
        }

        return $end;
    }

    /**
     *
     * 获取[get]参数
     * @param null $param 要获取的参数[key]
     * @param bool $format 是否格式化
     * @param mixed $default 初始值
     * @return array|float|int|mixed|string|null
     */
    protected function get($param = null, $format = true, $default = '')
    {

        $request = Yii::$app->request->get();

        $end = [];
        if ($param && isset($request[$param])) {

            // 非数组才进行去两端空格
            $end = $request[$param];
        } elseif (!isset($request[$param])) {

            $end = null;
        } else {

            $end = $request;
        }

        // 非空的格式化一下
        if ($end && !empty($end)) $end = $this->formatParams($end, $format);

        // 默认值
        if (empty($end) && isset($default)) {
            return $default;
        }

        return $end;
    }

    /**
     * 获取[request]参数|从[get]、[post]获取
     * @param null $param 要获取的参数[key]
     * @param bool $format 是否格式化
     * @param mixed $default 初始值
     * @return array|string|null
     */
    protected function request($param = null, $format = true, $default = '')
    {

        $request = [];
        try {
            $request = \Yii::$app->request->getBodyParams();
        } catch (Exception $err) {
            \Yii::error([
                "************************* 数据库错误 *************************",
                "\n\n\t*** 错误详情：获取[Request]参数出错 ***",
                "\n\n\t*** 错误行数：***",
                $err->getLine(),
                "\n\n\t*** 错误文件：***",
                $err->getFile(),
                "\n\n\t*** 错误信息：***",
                $err->getMessage(),
                "\n\n\t*** 错误详情: ***",
                $err->getTraceAsString()
            ], 'normal');
        }

        $end = [];
        if ($param && isset($request[$param])) {

            // 非数组才进行去两端空格
            $end = $request[$param];
        } elseif (!isset($request[$param])) {

            $end = null;
        } else {

            $end = $request;
        }

        // 非空的格式化一下
        if ($end && !empty($end)) $end = $this->formatParams($end, $format);

        // 默认值
        if (empty($end) && isset($default)) {
            return $default;
        }

        return $end;
    }

    /**
     * 请求参数格式化
     * @param $param
     * @param bool $format
     * @return float|int|string
     */
    protected function formatParams($param, $format = true)
    {

        // 没啥特殊需要 非数组去下空
        if (is_string($param) && $format === true) {
            return trim(strval($param));
        } elseif (is_array($param) && $format === true) {
            // 没啥特殊需要，数组直接返回
            return $param;
        }

        // 转化 - 字符
        if (in_array($format, ['str', 'string'])) {
            return trim(strval($param));
        }

        // 数字 - 小数
        $list = ['float', 'floatval', 'double', 'doubleval'];
        if (is_numeric($param) && in_array($format, $list)) {
            return floatval($param);
        }

        // 数字 - 剩余转为 整数
        $list = ['int', 'intval', 'integer', 'numeric'];
        if (is_numeric($param) && in_array($format, $list)) {
            return intval($param);
        }

        // 其余不做转换
        return $param;
    }

    /**
     * 手机端用户编号参数
     * @return array|mixed
     */
    protected function getAppUid()
    {

        return CommonModel::getAppUid();
    }

    /**
     * api返回的json
     * @param string $message
     * @param $code
     * @param array $data
     * @param null $jsonStr
     */
    protected function jsonEncode($message, $code, $data = [], $jsonStr = null)
    {

        // code 、文本空的 就是500 错误了
        if (empty($message) && empty($code)) {

            $message = '请求频繁，请稍后尝试';
            $code = 500;
        }

        // 检测错误编号 - 不在合法内 错误[code]赋值
        if (intval($code) < 200 || $code > 600) {
            $data['errorColumn'] = $code;
            $code = 500;
        }

        // [500]错误必须要 错需详细信息在 [data]里
        if ($code == 500) {

            $data['errorHint'] = empty($data['errorHint']) ? $message : $data['errorHint'];
            $message = '请求频繁，稍后尝试';
        }

        // 最终返回
        $result = [
            'msg' => $message, // 错误信息
            'no' => $code,  // 错误 code
            'data' => $data
        ];

        if (!$jsonStr) {

            $result = json_encode($result);
        } else {

            $result = $jsonStr . '(' . json_encode($result) . ');';
        }

        //设置响应对象
        $response = Yii::$app->response;
        $response->format = Response::FORMAT_JSON;
        $response->content = $result;
    }

    /**
     * 操作成功 json 返回
     * @param string $message
     * @param array $data
     * @param null $jsonStr
     */
    protected function jsonSuccess($message = '', $data = [], $jsonStr = null)
    {

        // 成功信息空的就是 成功了
        $message = $message ? $message : '成功';
        // 默认code就200
        return $this->jsonEncode($message, 200, $data, $jsonStr);
    }

    /**
     * 操作失败 json 返回
     * @param $message
     * @param $code
     * @param $data
     * @param null $jsonStr
     */
    protected function jsonFail($message, $code, $data = [], $jsonStr = null)
    {

        // 整体判断下|全部都是空返回 500 错误
        if (empty($message) && empty($code)) {

            $message = '';
            $code = 500;
        }

        // 错误信息空的就是 请求频繁了
        $message = $message ? $message : '';
        // 错误code 空的 500
        $code = empty($code) ? 500 : $code;

        return $this->jsonEncode($message, $code, $data, $jsonStr);
    }

    /**
     * json自定义返回
     * @param $data
     */
    protected function jsonCustom($data)
    {

        //设置响应对象
        $response = Yii::$app->response;
        $response->format = Response::FORMAT_JSON;
        $response->content = is_array($data) ? json_encode($data, JSON_UNESCAPED_UNICODE) : $data;
    }

    /**
     * 返回XML
     * @param array $data
     * @return string
     */
    protected function xmlReturn($data = [])
    {

        if (empty($data))

            return '';

        $xml = "<xml>";
        foreach ($data as $key => $val) {

            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }

        $xml .= "</xml>";

        // 设置响应对象
        $response = Yii::$app->response;
        $response->format = Response::FORMAT_XML;
        $response->content = $xml;
    }

    /**
     * 页面展示错误
     * @param int $code 错误码
     * @param string $message 错误信息
     * @param array $option 其他配置，包括：preUrl - 返回上一页连接，template - 错误模板
     * @return string
     */
    protected function showError($code = 400, $message = '请求频繁稍后尝试', $option = [])
    {

        // 默认赋值 - 错误码
        $code = !$code || intval($code) == 0 ? 400 : $code;
        // 默认赋值 - 错误标题
        $title = empty($option['title']) ? '出错啦' : $option['title'];
        // 默认赋值 - 错误信息
        $message = !$message ? '请求频繁稍后尝试' : $message;
        // 默认赋值 - 错误返回连接
        $preUrl = empty($option['preUrl']) ? $this->request->referrer : $option['preUrl'];
        // 默认赋值 - 错误模板路径
        $template = empty($option['template']) ? '@app/views/site/error.php' : $option['template'];

        return $this->render($template, [
            'title' => $title,
            'status' => $code,
            'message' => $message,
            'previousPage' => $preUrl
        ]);
    }
}
